#include "MarsPrecompile.h"

#include "MarsConstantMgr.h"

using namespace Graphics;
using namespace Core;

ConstantMgr* ConstantMgr::ms_pConstantMgr = 0;

void ConstantMgr::Destroy()
{
	SAFE_DELETE( ms_pConstantMgr );
}

ConstantMgr::ConstantMgr()
{

}

ConstantMgr::~ConstantMgr()
{
	Shutdown();
}

bool ConstantMgr::Initialize()
{
	return true;
}

void ConstantMgr::Shutdown()
{
	ConstantsMapItr it = m_mapConstants.begin();
	ConstantsMapItr end = m_mapConstants.end();

	for ( ; it != end; ++it )
	{
		std::vector< VRamBuffer* >& arr = it->second;

		for ( Core::uint32 i = 0; i < arr.size(); ++i )
		{
			SAFE_DELETE( arr[ i ] );
		}
	}

	m_mapConstants.clear();
}

VRamBuffer* ConstantMgr::AllocateConstantBuffer( Core::uint32 iSize )
{
	VRamBuffer* pBuffer = new VRamBuffer( VRamBuffer::BufferType_Constant, D3D11_USAGE_DEFAULT );
	if ( !pBuffer->Create( NULL, iSize ) )
	{
		SAFE_DELETE( pBuffer );
	}

	ConstantsMapItr it = m_mapConstants.find( iSize );

	if ( it == m_mapConstants.end() )
	{
		m_mapConstants.insert( std::make_pair( iSize, std::vector< VRamBuffer* >() ) );
	}

	m_mapConstants[ iSize ].push_back( pBuffer );

	return pBuffer;
}

VRamBuffer* ConstantMgr::GetConstantBuffer( Core::uint32 iSize )
{
	ConstantsMapItr it = m_mapConstants.find( iSize );
	VRamBuffer* pFreeBuffer = NULL;

	if ( it == m_mapConstants.end() )
	{
		pFreeBuffer = AllocateConstantBuffer( iSize );
	}
	else
	{
		VRamBuffer** pArrayVRamBuffer = &it->second[0];
		for ( Core::uint32 i = 0; i < it->second.size(); ++i )
		{
			VRamBuffer* pVRamBuffer = pArrayVRamBuffer[ i ];
			if ( !pVRamBuffer->IsUsing() )
			{
				pVRamBuffer->SetUsing( true );
				pFreeBuffer = pVRamBuffer;
				break;
			}
		}

		if ( !pFreeBuffer )
		{
			pFreeBuffer = AllocateConstantBuffer( iSize );
		}
	}
	
	return pFreeBuffer;
}

